var FG;
if (!FG)
    FG = {};


FG.PITEM_TYPE_DICT = {
    'Point': '点',
    'Rect': '面',
    'MultiPolygon': '多边形',
    'MultiLine': '线'
};

FG.Snapshot = DX.BBModel.extend({
    urlRoot: '/api/fg/snapshot',
    tagField: 'uuid'
});

FG.SnapshotList = DX.BBCollection.extend({
    model: FG.Snapshot,
    tagField: 'uuid',

    initialize: function() {
        this.on('add', function(model){
            DX.shout('db:snapshot:add', model)
        });
        // this.on('update', function(model){
        //     DX.shout('db:snapshot:update', model)
        // });
        this.on('change', function(model){
            DX.shout('db:snapshot:change', model)
        });
        this.on('remove', function(model){
            DX.shout('db:snapshot:del', model)
        })
    },

    parse: function(response) {
        var snapshots = response.snapshots;
        // TODO: sort etc.
        return snapshots;
    }

});


FG.ProjectItem = DX.BBModel.extend({
    urlRoot: '/api/fg/pitem',
    tagField: 'uuid',
    className: 'ProjectItem',
    
    initialize: function() {
        // this.set('loading', true);
    },

    parse: function(response) {
        var this_ = this;
        var uuid = response.uuid;

        if (!!this.get('loading')) {
            return response;
        }
    
        this.set('loading', true, {silent: true});

        if (!_.has(this, 'snapshotList')) {
            this.snapshotList = new FG.SnapshotList([], {});
            this.snapshotList.url = '/api/fg/pitem_snapshots/' + uuid;
        }
        this.snapshotList.fetch({async: false});

        this.packManager = FG.getPackManager();
    
        this.dsvList = [];
        this.variableDict = {};
        var allDFDs = [];
        this.set('hasDsvList', false, {silent: true});  //为了使dsvList加载完之后的update事件有效, 所以用BB内部的属性列表.

        if (_.has(response, 'data_briefs')) {
            var dsvDFD = $.Deferred();
            allDFDs.push(dsvDFD);
            var dfds = [];
            _.each(response.data_briefs, function(brief){
                DX.error(brief);
                var dfd = $.Deferred();
                dfds.push(dfd);
                this_.packManager.getDataset(brief.dataset).done(function(dataset) {
                    //DX.warn(schema.attributes)
                    if (!dataset) {
                        dfd.resolve(null)
                    } else {
                        var dsv = dataset.getDSV({data: brief});
                        dsv.priority = dataset.get('priority');
                        this_.dsvList.push(dsv);
                        //DX.warn(dsv);
                        dfd.resolve(dsv);
                    }
                    
                });
            });
            $.when.apply(this, dfds).done(function() {
                this_.variableDict = FG.genVariableDict(this_.dsvList, this_.packManager);
                this_.dsvList = _.sortBy(this_.dsvList, 'priority');
                this_.set('hasDsvList', true, {silent: true});
                dsvDFD.resolve();
            });
        }
        // TODO: parse extra

        if (response.item_type === 'MultiPolygon') {
            this.set('hasMapData', false, {silent: true});
            var mapDataDfd = FG.mapPool.getDfd(response.geometry_uri);
            mapDataDfd.done(function(mapData) {
                this_.mapData = mapData;  //可能为null.
                this_.set('hasMapData', !!this_.mapData, {silent: true});
            });
            allDFDs.push(mapDataDfd);
    
        }

        $.when.apply(this, allDFDs).done(function() {
            this_.set('loading', false, {silent: true});
            if (!!this_.get('uuid')) {
                this_.trigger('change', this_);
            }
        });

        return response
    },

    hasData: function() {
        if (_.has(this, 'dsvList') && !_.isEmpty(this.dsvList)) {
            return true;
        } else {
            return false;
        }
    }
});

FG.ProjectItemList = DX.BBCollection.extend({
    model: FG.ProjectItem,
    tagField: 'uuid',

    parse: function(response) {
        var items = response.items;
        // TODO: sort by order
        return items;
    },

    initialize: function() {
        var this_ = this;
        this.on('add', function(model){
            DX.shout('db:pitem:add', model);
            //model.snapshotList.fetch();
        });
        // this.on('update', function(model){
        //     DX.shout('db:pitem:update', model)
        // });
        this.on('change', function(model){
            DX.shout('db:pitem:update', model)
        });
        this.on('remove', function(model){
            DX.shout('db:pitem:del', model)
        });
    }
});

FG.Project = DX.BBModel.extend({
    urlRoot: '/api/fg/project',
    tagField: 'uuid',

    parse: function (response) {
        var this_ = this;
        var uuid = response.uuid;
        DX.print("Project parsing: " + uuid);
        if (!_.has(this, 'itemList')) {
            this.itemList = new FG.ProjectItemList([], {});
            this.itemList.url = '/api/fg/project_items/' + uuid;
        }
        // 不要在这里取itemList的内容, 否则所有project在加载时都取各自的itemList, 就乱套了.
        // 在switchProject时随着project的fetch, 手动对itemList进行fetch.
        //this.itemList.fetch();

        return response
    }
});

FG.ProjectList = DX.BBCollection.extend({
    model: FG.Project,
    url: '/api/fg/project',
    tagField: 'uuid',

    initialize: function() {
        this.on('add', function(model){
            DX.shout('db:project:add', model)
        });
        // this.on('update', function(model){
        //     DX.shout('db:project:update', model)
        // });
        this.on('change', function(model){
            DX.shout('db:project:update', model)
        });
        this.on('remove', function(model){
            DX.shout('db:project:del', model)
        })
    }
});

FG.ProjectType = DX.BBModel.extend({
    urlRoot: '/api/fg/project_type',
    tagField: 'name'
});

FG.ProjectTypeList = DX.BBCollection.extend({
    model: FG.ProjectType,
    url: '/api/fg/project_type',
    tagField: 'name',
    
    initialize: function() {
        var this_ = this;
        this.on('add', function(model){
            DX.shout('db:ptype:add', model)
        });
        this.on('change', function(model){
            DX.shout('db:ptype:update', model)
        });
        this.on('remove', function(model){
            DX.shout('db:ptype:del', model)
        });
    }
});

FG.ProjectCore = function() {
    var this_ = this;
    this.moduleInfo = {
        name: 'projectCore',
        zhName: '工程核心',
        desc: '',
        exportList: []
    };
    
    this.projectTypeList = new FG.ProjectTypeList();
    this.projectList = new FG.ProjectList();
    this.packManager = FG.getPackManager();

    this.initialize = function() {
        this.connectSignals();
        this.projectTypeList.fetch();
        DX.print("init");
        // DX.shout('db:projectlist:load:begin');
        // this.projectList.fetch({
        //     success: function(){
        //         DX.shout('db:projectlist:load:end');
        //     }
        // })
        this.refreshProjectList();
    };

    this.switchProject = function(model) {
        // TODO: uuid支持
        if (typeof model === 'undefined') {
            if (this.projectList.length == 0) {
                this.project = model;
                DX.shout('db:project:switch');
                return;
                //this.project = this.projectList.createEntry({uuid: DX.gen_uuid8(), name: '未命名工程'});
            } else {
                this.project = this.projectList.at(0);
            }
        } else {
            this.project = model
        }

        DX.shout('db:project:load:begin', this.project);
        DX.shout('db:project:switch', this.project);
        //if (typeof this.project.id === undefined) {
        //    DX.error("Project not ready, not fetching.");
        //    return;
        //}
        DX.print("project to fetch");
        this.project.fetch({
            success: function(model){
                model.itemList.fetch({
                    success: function() {
                        DX.shout('db:project:load:end', this_.project);
                    }
                });
            }
        });
    };

    this.switchSnapshot = function(snapshot) {
        // switch to the project
        // switch to the item and highlight it and opens it's widget
        var pitem = snapshot.get('project_item_uuid');
        DX.shout('db:pitem:switch', pitem);

        DX.shout('db:snapshot:switch', snapshot);


        // switch to the DSV
        // switch to the coords
        // load the the data and render
    };
    
    // 已整理

    this.pushProject = function(project) {
        this.projectList.pushEntry(project);
    };
    
    this.delProject = function(project) {
        var needSwitch = !!this_.project && (project.getTag() === this_.project.getTag());
        this_.projectList.deleteEntry(project);
        if (needSwitch) {
            this_.switchProject();
        }
    };
    
    this.pushPItem = function(opts) {
        opts = _.extend({}, opts);
        if (!_.has(opts, 'project')) {
            if (!this_.project) {
                // TODO 
                DX.alert('请先创建或选择一个工程');
                return;
            } else {
                opts.project = this_.project.get('uuid');
            }
        }
        
        if (!opts.project) {
            opts.project = this_.project.get('uuid');
        }
        
        if (!opts.name) {
            var newFeatureID = this_.project.itemList.where({item_type: opts.item_type}).length + 1;
            opts.name = FG.PITEM_TYPE_DICT[opts.item_type] + ": " + newFeatureID;
        }
        
        opts = _.pick(opts,
            'name', 'desc', 'item_type', 'info', 'project', 'uuid',
            'order', 'showing_status'
        );

        if (!this_.project) {
            //直接通过pitem接口添加
            // TODO
        } else {
            this_.project.itemList.pushEntry(opts);
        }
    };
    
    this.delPItem = function(pitem) {
        // TODO: 加上字符串(uuid)支持, 以及非当前活动project的处理.
        if (!this.project) {
            return;
        }
        this.project.itemList.deleteEntry(pitem);
    };
    
    this.pushSnapshot = function(opts) {
        // TODO: 加上对snapshot对象的处理能力, 而非仅仅支持opts.
        opts = _.clone(opts);
        var ssOpts = {
            uuid: opts.uuid,
            project_item_uuid:opts.pitem_uuid,
            caption: opts.caption,
            desc: opts.desc,
            html: opts.html,
            status: opts.status,
            thumbnail: opts.thumbnail,
            item_default: opts.uuid === opts.pitem_uuid
        };
        var oldSnapshot = opts.pitem.snapshotList.getByTag(opts.uuid);
        if (!oldSnapshot) {
            opts.pitem.snapshotList.createEntry(ssOpts);
        } else {
            oldSnapshot.set(ssOpts);
            var changed = oldSnapshot.changedAttributes();
            var bigChanges = _.omit(changed, 'create_dt', 'access_dt', 'modify_dt', 'caption');
            if (!!changed && !_.isEmpty(bigChanges)) {
                oldSnapshot.save();
            }
        }
    };
    
    this.delSnapshot = function(snapshot) {
        // TODO: 加上字符串(uuid)支持, 以及非当前活动project的处理.
        
        var pitem_uuid = snapshot.get('project_item_uuid');
        var pitem = this_.project.itemList.getByTag(pitem_uuid);
        if (typeof pitem === 'undefined')
            return;
        pitem.snapshotList.deleteEntry(snapshot);
    };

    this.refreshProjectList = function() {
        DX.shout('db:projectlist:load:begin');
        this_.projectList.fetch({
            success: function(){
                DX.shout('db:projectlist:load:end');
            }
        });
    };
    
    this.refreshProject = function(project) {
        if (!project && !this_.project) {
            return;
        }
        //TODO: project可为uuid.
        var refreshUrl;
        if (!project || project.get('uuid') === this_.project.get('uuid')) {
            refreshUrl = '/update_project_items_briefs/' + this_.project.get('uuid');
            DX.shout('db:project:load:begin', this_.project);
            $.ajax(refreshUrl, {
                dataType: 'json',
                success: function(data) {
                    if (data.result === 'succeeded') {
                        this_.switchProject(this_.project);
                    }
                }
            })
        } else {
            refreshUrl = '/update_project_items_briefs/' + project.get('uuid');
            $.ajax(refreshUrl, {
                dataType: 'json',
                success: function(data) {}
            })
        }
    };
    
    this.connectSignals = function() {
        DX.on('project:add!', function(project) { this_.pushProject(project); });
        DX.on('project:update!', function(project) { this_.pushProject(project); });
        DX.on('project:push!', function(project) { this_.pushProject(project); });
        DX.on('project:del!', function(project) { this_.delProject(project); });
    
        DX.on('pitem:add!', function(pitem) { this_.pushPItem(pitem); });
        DX.on('pitem:update!', function(pitem) { this_.pushPItem(pitem); });
        DX.on('pitem:push!', function(pitem) { this_.pushPItem(pitem); });
        DX.on('pitem:del!', function(pitem) { this_.delPItem(pitem); });
    
        DX.on('snapshot:add!', function(snapshot) { this_.pushSnapshot(snapshot); });
        DX.on('snapshot:update!', function(snapshot) { this_.pushSnapshot(snapshot); });
        DX.on('snapshot:push!', function(snapshot) { this_.pushSnapshot(snapshot); });
        DX.on('snapshot:del!', function(snapshot) { this_.delSnapshot(snapshot); });
    
        DX.on('project:switch!', function(project) { this_.switchProject(project) });
        DX.on('snapshot:switch!', function(snapshot) { this_.switchSnapshot(snapshot) });
    
        DX.on('project:refresh!', function(project) { this_.refreshProject(project) });
        DX.on('projectlist:refresh!', function(){ this_.refreshProjectList(); });
    };

    this.initialize();
};


